﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.Reflection;
using PloobsEngine.Commands;

namespace PloobsEngine.Components
{
    
    public class ComponentManager 
    {
        private EngineStuff _es;
        private IDictionary<String, IComponent> _comps = new Dictionary<String, IComponent>();
        private List<IComponent> _updateables = new List<IComponent>();
        private List<IComponent> _actives = new List<IComponent>();
        private List<IComponent> _preDrawables = new List<IComponent>();
        private List<IComponent> _posDrawables = new List<IComponent>();

        public ComponentManager(EngineStuff es)
        {
            this._es = es;           

        }


        public void Initialize()
        {
            foreach (IComponent item in _actives)
            {
                item.Initialize();
                CommandProcessor.getCommandProcessor().Register(item);
            }
        }
        public void Update(GameTime gt)
        {
            foreach (IComponent item in _updateables)
            {
                item.Update(gt);
            }            
        }

        public IList<IComponent> GetPreDraw()
        {
            return _preDrawables;
        }
        public IList<IComponent> GetPosDraw()
        {
            return _posDrawables;
        }

        public void PreDraw(GameTime gt, Matrix activeView, Matrix activeProjection)
        {
            foreach (IComponent item in _preDrawables)
            {
                item.PreDraw(gt,activeView,activeProjection);
            }
        }
        public void AfterDraw(GameTime gt, Matrix activeView, Matrix activeProjection)
        {
            foreach (IComponent item in _posDrawables)
            {
                item.AfterDraw(gt,activeView,activeProjection);
            }
        }
        public void LoadContent(EngineStuff engine)
        {
            foreach (IComponent item in _actives)
            {
                item.LoadContent(engine);
            }
        }

        public void AddComponent(IComponent comp)
        {
                    switch (comp.ComponentType)
                    {
                        case ComponentType.PRE_DRAWABLE:
                            _preDrawables.Add(comp);
                            break;
                        case ComponentType.POS_DRAWABLE:
                            _posDrawables.Add(comp);
                            break;
                        case ComponentType.UPDATEABLE:
                            _updateables.Add(comp);
                            break;
                        case ComponentType.PRE_DRAWABLE_AND_UPDATEABLE:
                            _preDrawables.Add(comp);
                            _updateables.Add(comp);
                            break;
                        case ComponentType.POS_DRAWABLE_AND_UPDATEABLE:
                            _posDrawables.Add(comp);
                            _updateables.Add(comp);
                            break;
                        case ComponentType.NONE:
                            break;
                        default:
                            break;
                    }
                   _actives.Add(comp);                            
                  _comps.Add(comp.getMyName(), comp);
                  _comps[comp.getMyName()].Initialize();
                  _comps[comp.getMyName()].LoadContent(_es);
                  CommandProcessor.getCommandProcessor().Register(_comps[comp.getMyName()]);

        }

        public bool IsActive(String name)
        {
            if (_comps.ContainsKey(name))
            {
                return _actives.Contains(_comps[name]);
            }
            return false;
        }
      
        public void RemoveComponent(String name)
        {
            switch (_comps[name].ComponentType)
            {
                case ComponentType.PRE_DRAWABLE:
                    _preDrawables.Remove(_comps[name]);
                    break;
                case ComponentType.POS_DRAWABLE:
                    _posDrawables.Remove(_comps[name]);
                    break;
                case ComponentType.UPDATEABLE:
                    _updateables.Remove(_comps[name]);
                    break;
                case ComponentType.PRE_DRAWABLE_AND_UPDATEABLE:
                    _preDrawables.Remove(_comps[name]);
                    _updateables.Remove(_comps[name]);
                    break;
                case ComponentType.POS_DRAWABLE_AND_UPDATEABLE:
                    _posDrawables.Remove(_comps[name]);
                    _updateables.Remove(_comps[name]);
                    break;
                case ComponentType.NONE:
                    break;
                default:
                    break;
            }

            _actives.Remove(_comps[name]);
        }

    }
}
